

#ifndef  __USB_MSG_H__
#define  __USB_MSG_H__




typedef struct {

	uint16_t rqc;
    uint16_t seq;

	int  mlen;
	int  offs;
	uint8_t * data;

} umsg_t;



/**/
static inline void umsg_reset_ofs( umsg_t * pmsg )
{
    /* 用户代码的 read 和 write 处理, 跳过 RQC 2个字节.. */
    pmsg->offs = 4;
    return;
}


static inline uint8_t umsg_get_u8( umsg_t * pmsg )
{
    int ofs = pmsg->offs;

    /**/
    pmsg->offs += 1;
    return pmsg->data[ofs];
}


static inline uint16_t umsg_get_u16( umsg_t * pmsg )
{
    int ofs = pmsg->offs;
    uint16_t temp;

    /* Little Endian */
    temp = pmsg->data[ofs + 1];
    temp = (temp << 8) | pmsg->data[ofs];

    /**/
    pmsg->offs += 2;
    return temp;
}



static inline uint32_t umsg_get_u32( umsg_t * pmsg )
{
    int ofs = pmsg->offs;
    uint32_t temp;

    /**/
    temp = pmsg->data[ ofs + 3 ];
    temp = ( temp << 8 ) | pmsg->data[ ofs + 2 ];
    temp = ( temp << 8 ) | pmsg->data[ ofs + 1 ];
    temp = ( temp << 8 ) | pmsg->data[ ofs ];

    /**/
    pmsg->offs += 4;
    return temp;
}


static inline int32_t umsg_get_i32( umsg_t * pmsg ) {
    return (int32_t)umsg_get_u32( pmsg );
}



/*
还没有读出的 剩余数据 长度.
*/
static inline int umsg_remains( umsg_t * pmsg )
{
    return (int)( (uint16_t)pmsg->mlen - pmsg->offs );
}

/*
让 offset 跳过一些数据(空间).
在读数据场景中, 用于跳过一些不关心的内容.
也可以用于写数据场景中, 为了对齐下一个字段而添加 padding.
*/
static inline void umsg_skip( umsg_t * pmsg, int tsiz )
{
    pmsg->offs += tsiz;
    return;
}


static inline void * umsg_curr( umsg_t * pmsg )
{
    return (void *)( pmsg->data + pmsg->offs );
}


static inline void umsg_add_u8( umsg_t * pmsg, uint8_t uv )
{
    int ofs = pmsg->offs;

    pmsg->data[ ofs ] = uv;
    pmsg->offs = ofs + 1;
    return;
}


static inline void umsg_add_u16( umsg_t * pmsg, uint16_t uv )
{
    int ofs = pmsg->offs;

    pmsg->data[ ofs ] = uv & 0xFF;
    pmsg->data[ ofs + 1 ] = (uv >> 8) & 0xFF;
    pmsg->offs = ofs + 2;
    return;
}


static inline void umsg_add_u24( umsg_t * pmsg, uint32_t uv )
{
    int ofs = pmsg->offs;

    pmsg->data[ ofs ] = uv & 0xFF;
    pmsg->data[ ofs + 1 ] = (uv >> 8) & 0xFF;
    pmsg->data[ ofs + 2 ] = (uv >> 16) & 0xFF;
    
    pmsg->offs = ofs + 3;
    return;
}


/* pack data to umsg */
static inline void umsg_add_u32( umsg_t * pmsg, uint32_t uv )
{
    int ofs = pmsg->offs;

    /* little endian */
    pmsg->data[ ofs ] = uv & 0xFF;
    pmsg->data[ ofs + 1 ] = (uv >> 8) & 0xFF;
    pmsg->data[ ofs + 2 ] = (uv >> 16) & 0xFF;
    pmsg->data[ ofs + 3 ] = (uv >> 24) & 0xFF;

    /**/
    pmsg->offs = ofs + 4;
    return;
}


static inline void umsg_add_i32( umsg_t * pmsg, int32_t iv )
{
    umsg_add_u32( pmsg, (uint32_t)iv );
    return;
}



#endif


